/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-10-25     郭紧合       the first version
 */
#ifndef APPLICATIONS_LCD_H_
#define APPLICATIONS_LCD_H_

#include <rtthread.h>
#include "board.h"

//=========================================电源接线================================================//
//5V接DC 5V电源
//3V3 不用接
//GND接地
//=======================================液晶屏数据线接线==========================================//
//本模块默认数据总线类型为8位并行模式
//8位模式接线：8位模式模块接低8位总线，即:
//液晶屏LCD_D0对应单片机PE4
//液晶屏LCD_D1对应单片机PA1
//液晶屏LCD_D2对应单片机PA6
//液晶屏LCD_D3对应单片机PE0
//液晶屏LCD_D4对应单片机PE1
//液晶屏LCD_D5对应单片机PA5
//液晶屏LCD_D6对应单片机PA4
//液晶屏LCD_D7对应单片机PA3
//=======================================液晶屏控制线接线==========================================//
//LCD_RST   接PE6    //复位信号
//LCD_CS    接PE7    //片选信号
//LCD_RS    接PA0    //寄存器/数据选择信号
//LCD_WR    接PE3    //写信号
//LCD_RD    接PE2    //读信号

//LCD重要参数集
typedef struct
{
    uint16_t width;          //LCD 宽度
    uint16_t height;         //LCD 高度
    uint16_t id;             //LCD ID
    uint8_t  dir;            //横屏还是竖屏控制：0，竖屏；1，横屏。
    uint16_t  wramcmd;       //开始写gram指令
    uint16_t  setxcmd;       //设置x坐标指令
    uint16_t  setycmd;       //设置y坐标指令
}_lcd_dev;

//LCD参数
extern _lcd_dev lcddev; //管理LCD重要参数
/////////////////////////////////////用户配置区///////////////////////////////////
//支持横竖屏快速定义切换，支持8/16位模式切换
#define USE_HORIZONTAL      1   //定义是否使用横屏      0,不使用.1,使用.
#define LCD_USE8BIT_MODEL   1   //定义数据总线是否使用8位模式 0,使用16位模式.1,使用8位模式
//////////////////////////////////////////////////////////////////////////////////
//定义LCD的尺寸
#if USE_HORIZONTAL==1   //使用横屏
#define LCD_W 480
#define LCD_H 320
#else
#define LCD_W 320
#define LCD_H 480
#endif

//TFTLCD部分外要调用的函数
extern uint16_t  POINT_COLOR;//默认红色
extern uint16_t  BACK_COLOR; //背景颜色.默认为白色

////////////////////////////////////////////////////////////////////
//-----------------LCD端口定义----------------
//如果使用官方库函数定义下列底层，速度将会下降到14帧每秒，建议采用我司推荐方法
//以下IO定义直接操作寄存器，快速IO操作，刷屏速率可以达到28帧每秒！

#define LCD_CS_SET  rt_pin_write(20, PIN_HIGH)    //片选端口      PE7
#define LCD_RS_SET  rt_pin_write(0, PIN_HIGH)    //数据/命令     PA0
#define LCD_WR_SET  rt_pin_write(16, PIN_HIGH)    //写数据         PE3
#define LCD_RD_SET  rt_pin_write(15, PIN_HIGH)    //读数据        PE2
#define LCD_RST_SET rt_pin_write(19, PIN_HIGH)    //复位          PE6

#define LCD_CS_CLR  rt_pin_write(20, PIN_LOW)     //片选端口     PE7
#define LCD_RS_CLR  rt_pin_write(0, PIN_LOW)     //数据/命令    PA0
#define LCD_WR_CLR  rt_pin_write(16, PIN_LOW)     //写数据        PE3
#define LCD_RD_CLR  rt_pin_write(15, PIN_LOW)     //读数据       PE2
#define LCD_RST_CLR rt_pin_write(19, PIN_LOW)     //复位         PE6

//#define LCD_CS_SET  rt_pin_write(18, PIN_HIGH)    //片选端口      PE5
//#define LCD_RS_SET  rt_pin_write(20, PIN_HIGH)    //数据/命令     PE7
//#define LCD_WR_SET  rt_pin_write(9, PIN_HIGH)    //写数据         PB1
//#define LCD_RD_SET  rt_pin_write(10, PIN_HIGH)    //读数据        PB2
//#define LCD_RST_SET rt_pin_write(19, PIN_HIGH)    //复位          PE6
//
//#define LCD_CS_CLR  rt_pin_write(18, PIN_LOW)     //片选端口     PE5
//#define LCD_RS_CLR  rt_pin_write(20, PIN_LOW)     //数据/命令    PE7
//#define LCD_WR_CLR  rt_pin_write(9, PIN_LOW)     //写数据        PB1
//#define LCD_RD_CLR  rt_pin_write(10, PIN_LOW)     //读数据       PB2
//#define LCD_RST_CLR rt_pin_write(19, PIN_LOW)     //复位         PE6
//PB0~15,作为数据线
//注意：如果使用8位模式数据总线，则液晶屏的数据高8位是接到MCU的高8位总线上
//举例：如果接8位模式则本示例接线为液晶屏DB10-DB17对应接至单片机GPIOB_Pin8-GPIOB_Pin15
//举例：如果是16位模式：DB0-DB7分别接GPIOB_Pin0-GPIOB_Pin7,DB10-DB17对应接至单片机GPIOB_Pin8-GPIOB_Pin15
            //PA3 PA4 PA5 PE1 PE0 PA6 PA1 PE4
#define DATAOUT(x) {rt_pin_write(3, (x&0x80)); \
                    rt_pin_write(4, (x&0x40)); \
                    rt_pin_write(5, (x&0x20)); \
                    rt_pin_write(14, (x&0x10)); \
                    rt_pin_write(13, (x&0x08)); \
                    rt_pin_write(6, (x&0x04)); \
                    rt_pin_write(1, (x&0x02)); \
                    rt_pin_write(17, (x&0x01)); \
                    }; //数据输出
//            //PF0 PE0 PE1 PA5 PB0 PF1 PA6 PE3
//#define DATAOUT(x) {rt_pin_write(21, (x&0x80)); \
//                    rt_pin_write(13, (x&0x40)); \
//                    rt_pin_write(14, (x&0x20)); \
//                    rt_pin_write(5, (x&0x10)); \
//                    rt_pin_write(8, (x&0x08)); \
//                    rt_pin_write(22, (x&0x04)); \
//                    rt_pin_write(6, (x&0x02)); \
//                    rt_pin_write(16, (x&0x01)); \
//                    }; //数据输出
//#define DATAIN     GPIOB->IDR;   //数据输入
//////////////////////////////////////////////////////////////////////


//扫描方向定义
#define L2R_U2D  0 //从左到右,从上到下
#define L2R_D2U  1 //从左到右,从下到上
#define R2L_U2D  2 //从右到左,从上到下
#define R2L_D2U  3 //从右到左,从下到上

#define U2D_L2R  4 //从上到下,从左到右
#define U2D_R2L  5 //从上到下,从右到左
#define D2U_L2R  6 //从下到上,从左到右
#define D2U_R2L  7 //从下到上,从右到左

#define DFT_SCAN_DIR  R2L_U2D  //默认的扫描方向


//画笔颜色
#define WHITE       0xFFFF
#define BLACK       0x0000
#define BLUE        0x001F
#define BRED        0XF81F
#define GRED                0XFFE0
#define GBLUE               0X07FF
#define RED         0xF800
#define MAGENTA     0xF81F
#define GREEN       0x07E0
#define CYAN        0x7FFF
#define YELLOW      0xFFE0
#define BROWN           0XBC40 //棕色
#define BRRED           0XFC07 //棕红色
#define GRAY            0X8430 //灰色
//GUI颜色

#define DARKBLUE         0X01CF //深蓝色
#define LIGHTBLUE        0X7D7C //浅蓝色
#define GRAYBLUE         0X5458 //灰蓝色
//以上三色为PANEL的颜色

#define LIGHTGREEN      0X841F //浅绿色
//#define LIGHTGRAY     0XEF5B //浅灰色(PANNEL)
#define LGRAY                   0XC618 //浅灰色(PANNEL),窗体背景色

#define LGRAYBLUE       0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE          0X2B12 //浅棕蓝色(选择条目的反色)

extern uint16_t BACK_COLOR, POINT_COLOR ;

void LCD_Init(void);
void LCD_DisplayOn(void);
void LCD_DisplayOff(void);
void LCD_Clear(uint16_t Color);
void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos);
void LCD_DrawPoint(uint16_t x,uint16_t y);//画点
//uint16_t  LCD_ReadPoint(uint16_t x,uint16_t y); //读点 //无
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
//void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void LCD_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd);
void LCD_DrawPoint_16Bit(uint16_t color);
//uint16_t LCD_RD_DATA(void);//读取LCD数据  //无
void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue);
void LCD_WR_DATA(uint16_t data);
//uint16_t LCD_ReadReg(uint8_t LCD_Reg);//无
void LCD_WriteRAM_Prepare(void);
//void LCD_WriteRAM(uint16_t RGB_Code);//无
//uint16_t LCD_ReadRAM(void);//无
//uint16_t LCD_BGR2RGB(uint16_t c);//无
void LCD_SetParam(void);
//void LCD_direction(uint8_t direction );

void GUI_DrawPoint(uint16_t x,uint16_t y,uint16_t color);
void LCD_Fill(uint16_t sx,uint16_t sy,uint16_t ex,uint16_t ey,uint16_t color);
//void Draw_Circle(uint16_t x0,uint16_t y0,uint16_t fc,uint8_t r);   //无
void LCD_ShowChar(uint16_t x,uint16_t y,uint16_t fc, uint16_t bc, uint8_t num,uint8_t size,uint8_t mode);
void LCD_ShowString(uint16_t x,uint16_t y,uint8_t size,uint8_t *p,uint8_t mode);
//void LCD_ShowNum(uint16_t x,uint16_t y,uint32_t num,uint8_t len,uint8_t size);
//void LCD_Show2Num(uint16_t x,uint16_t y,uint16_t num,uint8_t len,uint8_t size,uint8_t mode); //无
//void GUI_DrawFont16(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s,uint8_t mode);//无
//void GUI_DrawFont24(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s,uint8_t mode);//无
//void GUI_DrawFont32(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *s,uint8_t mode);//无
//void Show_Str(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *str,uint8_t size,uint8_t mode);//无
//void Gui_StrCenter(uint16_t x, uint16_t y, uint16_t fc, uint16_t bc, uint8_t *str,uint8_t size,uint8_t mode);//无
void Gui_Drawbmp16(uint16_t x,uint16_t y,const unsigned char *p); //显示40*40 QQ图片
void gui_circle(int xc, int yc,uint16_t c,int r, int fill);

//如果仍然觉得速度不够快，可以使用下面的宏定义,提高速度.
//注意要去掉lcd.c中void LCD_WR_DATA(u16 data)函数定义哦
/*
#if LCD_USE8BIT_MODEL==1//使用8位并行数据总线模式
    #define LCD_WR_DATA(data){\
    LCD_RS_SET;\
    LCD_CS_CLR;\
    DATAOUT(data);\
    LCD_WR_CLR;\
    LCD_WR_SET;\
    DATAOUT(data<<8);\
    LCD_WR_CLR;\
    LCD_WR_SET;\
    LCD_CS_SET;\
    }
    #else//使用16位并行数据总线模式
    #define LCD_WR_DATA(data){\
    LCD_RS_SET;\
    LCD_CS_CLR;\
    DATAOUT(data);\
    LCD_WR_CLR;\
    LCD_WR_SET;\
    LCD_CS_SET;\
    }
#endif
*/

//9320/9325 LCD寄存器
#define R0             0x00
#define R1             0x01
#define R2             0x02
#define R3             0x03
#define R4             0x04
#define R5             0x05
#define R6             0x06
#define R7             0x07
#define R8             0x08
#define R9             0x09
#define R10            0x0A
#define R12            0x0C
#define R13            0x0D
#define R14            0x0E
#define R15            0x0F
#define R16            0x10
#define R17            0x11
#define R18            0x12
#define R19            0x13
#define R20            0x14
#define R21            0x15
#define R22            0x16
#define R23            0x17
#define R24            0x18
#define R25            0x19
#define R26            0x1A
#define R27            0x1B
#define R28            0x1C
#define R29            0x1D
#define R30            0x1E
#define R31            0x1F
#define R32            0x20
#define R33            0x21
#define R34            0x22
#define R36            0x24
#define R37            0x25
#define R40            0x28
#define R41            0x29
#define R43            0x2B
#define R45            0x2D
#define R48            0x30
#define R49            0x31
#define R50            0x32
#define R51            0x33
#define R52            0x34
#define R53            0x35
#define R54            0x36
#define R55            0x37
#define R56            0x38
#define R57            0x39
#define R59            0x3B
#define R60            0x3C
#define R61            0x3D
#define R62            0x3E
#define R63            0x3F
#define R64            0x40
#define R65            0x41
#define R66            0x42
#define R67            0x43
#define R68            0x44
#define R69            0x45
#define R70            0x46
#define R71            0x47
#define R72            0x48
#define R73            0x49
#define R74            0x4A
#define R75            0x4B
#define R76            0x4C
#define R77            0x4D
#define R78            0x4E
#define R79            0x4F
#define R80            0x50
#define R81            0x51
#define R82            0x52
#define R83            0x53
#define R96            0x60
#define R97            0x61
#define R106           0x6A
#define R118           0x76
#define R128           0x80
#define R129           0x81
#define R130           0x82
#define R131           0x83
#define R132           0x84
#define R133           0x85
#define R134           0x86
#define R135           0x87
#define R136           0x88
#define R137           0x89
#define R139           0x8B
#define R140           0x8C
#define R141           0x8D
#define R143           0x8F
#define R144           0x90
#define R145           0x91
#define R146           0x92
#define R147           0x93
#define R148           0x94
#define R149           0x95
#define R150           0x96
#define R151           0x97
#define R152           0x98
#define R153           0x99
#define R154           0x9A
#define R157           0x9D
#define R192           0xC0
#define R193           0xC1
#define R229           0xE5

#endif /* APPLICATIONS_LCD_H_ */
